function gewSphere(center,radius)
{
  if(center)
    this.center = center.dup();
  else
    this.center = new gewVec3();
  if(radius)
    this.radius = radius;
  else
    this.radius = -1;
  this.outerPlane = 0;// help VFC faster
}

gewSphere.prototype = {
  dup: function()
  {
    var sphere = new gewSphere();
    sphere.center = this.center.dup();
    sphere.radius = this.radius;
    sphere.outerPlane = this.outerPlane;
    return sphere;
  },
  copyFrom:function(rhs)
  {
    var center = rhs.center;
    this.outerPlane = rhs.outerPlane;
    this.center.set(center.x,center.y,center.z);
    this.radius = rhs.radius;    
  },
  addInternalPoint:function(point)
  {
    this.addInternalPointXYZ(point.x,point.y,point.z);
  },
  addInternalPointXYZ:function(x,y,z)
  {
    if(this.radius==-1)
    {
      this.center.set(x,y,z);
      this.radius = 0;
      return;
    }
    gewRegVec0.set(x,y,z); // d= gewRegVec0
    var center = this.center;
    center.sub(gewRegVec0,gewRegVec1); // dc = gewRegVec1
    // Check point d outside the sphere
    var radius = this.radius;
    if( gewRegVec1.getLength() > (radius+ 0.01) )
    {
      gewRegVec1.normalize();
      gewRegVec1.mulScalar(radius,gewRegVec1);
      gewRegVec1.add(gewRegVec0,gewRegVec1).add(center,gewRegVec1).divScalar(2,gewRegVec1);
      center.set(gewRegVec1.x,gewRegVec1.y,gewRegVec1.z);
      this.radius = gewRegVec0.sub(center,gewRegVec0).getLength(); 
    }
   /*
    var d = new gewVec3(x,y,z);
    // vector dc = center - vector d
    var center = this.center;
    var dc = center.sub(d);
    var radius = this.radius;    
    // Check point d outside the sphere
    if( dc.getLength() > (radius+ 0.01) )
    {
      dc.normalize();
      var t1 = dc.mulScalar(radius).add(d);
      var temp = center.add(t1).divScalar(2);
      center = temp.dup();
      radius = d.sub(center).getLength(); 
    }
    */
  },
  addInternalSphere:function(sphere)
  {
    var test = this.isContainSphere(sphere );
    if(test == GEW_IN )
      return;
    var center = this.center;
    var rhs_center = sphere.center;
    if(test == GEW_INTERNAL )
    {
      center.set(rhs_center.x,rhs_center.y,rhs_center.z);
      this.radius = sphere.radius;
    }                                 
    // Vector center-> _sphere.center
    rhs_center.sub(center,gewRegVec0).normalize(); // c1c2_n = gewRegVec0
    // Find the farthest point with this sphere that on _sphere
    gewRegVec0.mulScalar(sphere.radius,gewRegVec0);
    rhs_center.add(gewRegVec0,gewRegVec0); 
    this.addInternalPointXYZ(gewRegVec0.x,gewRegVec0.y,gewRegVec0.z);
  },
  isContainPoint:function(point)
  {
    point.sub(this.center,gewRegVec0);
    if( gewRegVec0.getLengthSquare() > (radius*radius) )
      return GEW_OUT;
    else
      return GEW_IN;       
  },
  isContainSphere:function(sphere)
  {
    var radius = this.radius;
    var rhs_radius = sphere.radius;
    this.center.sub(sphere.center,gewRegVec0);
    var d = gewRegVec0.getLength();
    if( d > ( radius + rhs_radius ) )
      return GEW_OUT;
    if( d < radius ) 
      return GEW_IN;
    if( d < rhs_radius )
      return GEW_INTERNAL;
    return GEW_INTERSECT;
  }
}
